package xyz.thoughtset.viewer.modules.ds.http.core.executor;

import lombok.SneakyThrows;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.parsing.XPathParser;
import org.apache.ibatis.reflection.ParamNameResolver;
import org.apache.ibatis.scripting.xmltags.XMLScriptBuilder;
import org.apache.ibatis.session.Configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponentsBuilder;
import xyz.thoughtset.viewer.executor.core.base.AbstractExecutor;
import xyz.thoughtset.viewer.executor.core.entity.QueryBody;
import xyz.thoughtset.viewer.modules.ds.core.factory.ConnectFactory;
import xyz.thoughtset.viewer.modules.ds.http.core.constant.RequireAttrConstant;
import xyz.thoughtset.viewer.modules.ds.http.core.constant.SupportTypeConstant;
import xyz.thoughtset.viewer.modules.ds.http.core.req.BaseReq;

import java.util.HashMap;
import java.util.Map;

@Component
public class HttpReqExecutor extends AbstractExecutor {
    @Autowired
    protected ConnectFactory connectFactory;
    public HttpReqExecutor() {
        super(SupportTypeConstant.SUPPORT_TYPE, true);
    }
    private final Configuration configuration = new Configuration();

    @Override
    protected Object exec(QueryBody queryBody, Map param) {
        return doQuery(queryBody.getQuery(),param, connectFactory.buildConnect(queryBody.getDsId(), BaseReq.class));
    }


    @SneakyThrows
    public Object doQuery(String sqlText, Object param, BaseReq baseReq) {
        XNode rootNode = buildRootNode(sqlText);
        XNode xNode = rootNode.evalNode("http|get|post");
        XNode payloadNode = rootNode.evalNode("/payload");
        Boolean useFormatUrl = xNode.getBooleanAttribute(RequireAttrConstant.USE_FORMAT_URL, RequireAttrConstant.USE_FORMAT_URL_DEFAULT);
        //#{
        XMLScriptBuilder builder = new XMLScriptBuilder(configuration, xNode, null);
        SqlSource sqlSource = builder.parseScriptNode();
        Object parameterObject = ParamNameResolver.wrapToMapIfCollection(param, null);
        BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
        String reqUrl = boundSql.getSql().trim()
                .replaceAll("\\s*","")
                .replace("?&","?");
        if (reqUrl.endsWith("?")){
            reqUrl = reqUrl.substring(reqUrl.length()-1,reqUrl.length());
        }
        String payload = null;
        if (payloadNode!=null){
            payload = new XMLScriptBuilder(configuration, payloadNode, null)
                    .parseScriptNode().getBoundSql(parameterObject).getSql().trim()
                    .replaceAll("\\s*","");
        }
        String resultJson = null;
        switch (xNode.getName().toLowerCase()){
            case "post":
                resultJson = baseReq.doPost(reqUrl, useFormatUrl, payload);
                break;
            case "get":
            default:
                resultJson = baseReq.doGet(reqUrl, useFormatUrl);
        }
//        List result = new ArrayList();
//        result.add(StringUtils.hasText(resultJson) ? objectMapper.readValue(resultJson, Map.class) : new HashMap<>());
        return StringUtils.hasText(resultJson) ? objectMapper.readValue(resultJson, Map.class) : new HashMap<>();
    }




}
